package com.link2room.optimus.facade.impl;

import com.link2room.bumblebee.constant.TagTypeConstant;
import com.link2room.bumblebee.dto.param.base.PmsReservationOptionParamDto;
import com.link2room.bumblebee.dto.param.base.TagBaseParamDto;
import com.link2room.bumblebee.dto.result.base.PmsReservationOptionDto;
import com.link2room.bumblebee.dto.result.base.TagBaseDto;
import com.link2room.common.constant.DefaultValue;
import com.link2room.common.dto.result.base.HotelBaseInfoDto;
import com.link2room.common.dto.result.base.MemberSessionDto;
import com.link2room.common.dto.threadlocal.ApiThreadLocal;
import com.link2room.common.entity.BaseEntity;
import com.link2room.common.jpa.condition.ConditionDetail;
import com.link2room.common.jpa.condition.L2RCondition;
import com.link2room.common.jpa.criteria.CriteriaUtil;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.mns.MNSUtil;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.ClassConverUtil;
import com.link2room.common.util.DateUtil;
import com.link2room.common.util.JacksonUtil;
import com.link2room.common.util.StringUtil;
import com.link2room.ironhide.dto.param.base.RoomtypeBaseParamDto;
import com.link2room.ironhide.dto.param.inside.HotelBaseInfoInsideParamDto;
import com.link2room.ironhide.dto.result.base.L2RHotelPictureDto;
import com.link2room.ironhide.dto.result.base.L2RHotelRmtypePictureDto;
import com.link2room.ironhide.dto.result.base.L2RRoomtypeDto;
import com.link2room.optimus.constant.BaseRateplanConstant;
import com.link2room.optimus.constant.OptimusMnsConstant;
import com.link2room.optimus.dto.param.api.BookStockApiParamDto;
import com.link2room.optimus.dto.param.api.MarketingApiParamDto;
import com.link2room.optimus.dto.param.api.MarketingQueryApiParamDto;
import com.link2room.optimus.dto.param.base.MarketingStockBaseParamDto;
import com.link2room.optimus.dto.result.api.*;
import com.link2room.optimus.dto.result.base.*;
import com.link2room.optimus.entity.*;
import com.link2room.optimus.facade.IMarketingApiFacadeService;
import com.link2room.optimus.feign.bumblebee.PmsReservationOptionFeignService;
import com.link2room.optimus.feign.bumblebee.TagBaseFeignService;
import com.link2room.optimus.feign.ironhide.HotelBaseInfoFeignService;
import com.link2room.optimus.feign.ironhide.RoomtypeFeignService;
import com.link2room.optimus.feign.rodimus.PointFeignService;
import com.link2room.optimus.feign.soundwave.PmsAvailFeignService;
import com.link2room.optimus.mapper.MarketingMapper;
import com.link2room.optimus.mapper.PriceStaticMapper;
import com.link2room.optimus.service.IMarketingService;
import com.link2room.optimus.util.MarketingUtil;
import com.link2room.optimus.util.PricePoolUtil;
import com.link2room.rodimus.constant.MemberConstant;
import com.link2room.rodimus.dto.param.base.PointBaseParamDto;
import com.link2room.rodimus.dto.result.base.PointCheckDto;
import com.link2room.soundwave.dto.param.inside.PmsRoomAvailInsideParamDto;
import com.link2room.soundwave.dto.result.base.PmsRmtypeAvailDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Time;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by sss on 2016/9/7.
 */
@Component("marketingApiFacadeService")
public class MarketingApiFacadeServiceImpl implements IMarketingApiFacadeService {
    @Resource
    private ICommonService commonService;
    @Resource
    private IMarketingService marketingService;
    @Autowired
    private HotelBaseInfoFeignService hotelBaseInfoFeignService;
    @Autowired
    private RoomtypeFeignService roomtypeFeignService;
    @Autowired
    private PmsReservationOptionFeignService pmsReservationOptionFeignService;
    @Autowired
    private PmsAvailFeignService pmsAvailFeignService;
    @Autowired
    private PointFeignService pointFeignService;
    @Autowired
    private TagBaseFeignService tagBaseFeignService;
    @Resource
    private MNSUtil mnsUtil;

    /**
     * 前端得到酒店产品列表
     * @param marketApiParamDto
     * @return
     * @throws Exception
     */
    @Override
    public MarketingApiDto getHotelMarketingList(MarketingApiParamDto marketApiParamDto)throws Exception{
        Date checkInDate=marketApiParamDto.getCheckInDate();
        Date checkOutDate = marketApiParamDto.getCheckOutDate();
        String checkInDatetime=marketApiParamDto.getCheckInDatetime();
        String checkOutDatetime=marketApiParamDto.getCheckOutDatetime();

        if(checkInDate==null){
            checkInDate=new Date();
            checkInDatetime=DateUtil.format(checkInDate,DateUtil.newFormat);
        }
        if(checkOutDate==null){
            checkOutDate=DateUtil.addDays(new Date(),1L);
            checkOutDatetime=DateUtil.format(checkOutDate,DateUtil.newFormat);
        }
        MarketingApiDto marketingApiDto=new MarketingApiDto();

        String memberLevel= MemberConstant.MEMBER_LEVEL.L0;
        if(StringUtil.isNotBlank(marketApiParamDto.getTicket())){
            MemberSessionDto memberSession= ApiThreadLocal.getMemberSessionThreadLocal();
            memberLevel=memberSession.getMemberLevel();
        }
        //塞入酒店信息
        HotelBaseInfoInsideParamDto hotelBaseInfoInsideParamDto =new HotelBaseInfoInsideParamDto();
        hotelBaseInfoInsideParamDto.setLhotelCode(marketApiParamDto.getLhotelCode());
        QueryResult<HotelBaseInfoDto> hotelBaseInfoDtoResult = hotelBaseInfoFeignService.hotelBaseInfoList(hotelBaseInfoInsideParamDto.paramToMap()).getQueryResult();
        HotelBaseInfoDto hotelBaseInfoDto=hotelBaseInfoDtoResult.getResultlist().get(0);
        marketingApiDto.setMarketingApiHotel(ClassConverUtil.copyProperties(hotelBaseInfoDto, MarketingApiHotelDto.class));
        List<String> lhotelCodes=new ArrayList<>();
        lhotelCodes.add(hotelBaseInfoDto.getLhotelCode());
        hotelBaseInfoInsideParamDto.setLhotelCodes(lhotelCodes);
        QueryResult<L2RHotelPictureDto> hotelBigPicsResult = hotelBaseInfoFeignService.hotelBigPics(hotelBaseInfoInsideParamDto.paramToMap()).getQueryResult();
        QueryResult<L2RHotelPictureDto> hotelPicsResult = hotelBaseInfoFeignService.hotelPics(hotelBaseInfoInsideParamDto.paramToMap()).getQueryResult();
        if(hotelBigPicsResult.getResultlist()!=null&&hotelBigPicsResult.getResultlist().size()>0){
            marketingApiDto.getMarketingApiHotel().setBigPic(hotelBigPicsResult.getResultlist().get(0));
        }
        marketingApiDto.getMarketingApiHotel().setPics(hotelPicsResult.getResultlist());
       /* HotelMinPrice queryHotelMinPrice=new HotelMinPrice();
        queryHotelMinPrice.setLhotelGroupCode(marketApiParamDto.getLhotelGroupCode());
        queryHotelMinPrice.setLhotelCode(marketApiParamDto.getLhotelCode());
        queryHotelMinPrice.setRsvDate(DateUtil.parseDateWevFormat(marketApiParamDto.getCheckInDatetime()));
        HotelMinPrice hotelMinPrice = commonService.findOneEQ(HotelMinPrice.class, queryHotelMinPrice);
        if(hotelMinPrice!=null){
            marketingApiDto.getMarketingApiHotel().setHotelMinPrice(hotelMinPrice.getMinPrice());
        }*/
        List<Date> dateList= DateUtil.getDates("1234560",checkInDate,DateUtil.addDays(checkOutDate,-1L));
        Integer advHours=DateUtil.getHourNum(new Date(),checkInDate);
        Integer stayDays=DateUtil.getDayNum(checkInDate,checkOutDate);
        Date time = DateUtil.parseTime(DateUtil.format(new Date(), DateUtil.timeNewFormat));
        List<String> usedateList=new ArrayList<>();
        List<Integer> weekds=new ArrayList<>();
        for(Date usedate:dateList){
            usedateList.add(DateUtil.format(usedate,DateUtil.webFormat));
            weekds.add(DateUtil.getDateWeek(usedate));
        }
        MarketingQueryApiParamDto marketingQueryApiParamDto =new MarketingQueryApiParamDto();
        marketingQueryApiParamDto.setLhotelGroupCode(marketApiParamDto.getLhotelGroupCode());
        marketingQueryApiParamDto.setLhotelCode(marketApiParamDto.getLhotelCode());
        marketingQueryApiParamDto.setCheckInDatetime(checkInDatetime);
        marketingQueryApiParamDto.setCheckOutDatetime(checkOutDatetime);
        marketingQueryApiParamDto.setPbChannel(marketApiParamDto.getPbChannel());
        marketingQueryApiParamDto.setAdvHours(advHours);
        marketingQueryApiParamDto.setStayDays(stayDays);
        marketingQueryApiParamDto.setTime(new Time(time.getTime()));
        marketingQueryApiParamDto.setUsedateList(usedateList);
        marketingQueryApiParamDto.setWeekds(weekds);
        marketingQueryApiParamDto.setMcCodeList(marketApiParamDto.getMcCodeList());
        //取得活动
        QueryResult<MarketingMapper> marketingResult = marketingService.getMarketingList(marketingQueryApiParamDto);
        if(marketingResult.getResultlist()!=null&&marketingResult.getResultlist().size()>0){
            List<String> mcCodeList=new ArrayList<>();
            HashMap<String,MarketingMapper> marketingMap=new HashMap<>();
            for(MarketingMapper marketing:marketingResult.getResultlist()){
                mcCodeList.add(marketing.getMcCode());
                marketing.getDesValue();
                marketingMap.put(marketing.getMcCode(),marketing);
            }

            //取得产品
            L2RCondition mcdConfition=new L2RCondition();
            mcdConfition.setAndConditions(new ConditionDetail[]{
                            new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ,marketApiParamDto.getLhotelGroupCode()),
                            new ConditionDetail(BaseEntity.BaseEntity_.lhotelCode.toString(), CriteriaUtil.Operator.EQ,marketApiParamDto.getLhotelCode()),
                            new ConditionDetail(MarketingCampaignsDetail.MarketingCampaignsDetail_.mcCode.toString(), CriteriaUtil.Operator.IN,mcCodeList),
                            new ConditionDetail(BaseEntity.BaseEntity_.isHalt.toString(), CriteriaUtil.Operator.EQ,DefaultValue.F)
            });
            QueryResult<MarketingCampaignsDetail> marketingDetailResult = commonService.findAllByCondition(MarketingCampaignsDetail.class, mcdConfition);
            List<MarketingCampaignsDetail> marketingDetailList = marketingDetailResult.getResultlist();

            List<String> mcdCodeList=Optional.ofNullable(marketingDetailList).map(list->list.stream().map(event->event.getMcdCode()).collect(Collectors.toList())).orElse(null);
            L2RCondition stockConfition=new L2RCondition();
            stockConfition.setAndConditions(new ConditionDetail[]{
                    new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ,marketApiParamDto.getLhotelGroupCode()),
                    new ConditionDetail(BaseEntity.BaseEntity_.lhotelCode.toString(), CriteriaUtil.Operator.EQ,marketApiParamDto.getLhotelCode()),
                    new ConditionDetail(MarketingCampaignsStock.MarketingCampaignsStock_.mcdCode.toString(), CriteriaUtil.Operator.IN,mcdCodeList),
                    new ConditionDetail(MarketingCampaignsStock.MarketingCampaignsStock_.rsvDate.toString(), CriteriaUtil.Operator.GTE,checkInDate),
                    new ConditionDetail(MarketingCampaignsStock.MarketingCampaignsStock_.rsvDate.toString(), CriteriaUtil.Operator.LT,checkOutDate)
            });
            QueryResult<MarketingCampaignsStock> marketingStockResult = commonService.findAllByCondition(MarketingCampaignsStock.class, stockConfition);
            List<MarketingCampaignsStock> marketingStockList = marketingStockResult.getResultlist();
            QueryResult<MarketingCampaignsStockSold> marketingStockSoldResult = commonService.findAllByCondition(MarketingCampaignsStockSold.class, stockConfition);
            List<MarketingCampaignsStockSold> marketingStockSoldList = marketingStockSoldResult.getResultlist();

            //取得房型
            RoomtypeBaseParamDto roomtypeBaseParamDto =new RoomtypeBaseParamDto();
            roomtypeBaseParamDto.setLhotelGroupCode(marketApiParamDto.getLhotelGroupCode());
            roomtypeBaseParamDto.setLhotelCode(marketApiParamDto.getLhotelCode());
            roomtypeBaseParamDto.setCurrentPage(marketApiParamDto.getCurrentPage());
            roomtypeBaseParamDto.setPageSize(marketApiParamDto.getPageSize());
            roomtypeBaseParamDto.setIsHalt(DefaultValue.F);
            QueryResult<L2RRoomtypeDto> hotelRoomTypeResult = roomtypeFeignService.listRoomtype(roomtypeBaseParamDto.paramToMap()).getQueryResult();
            List<L2RRoomtypeDto> rmtypeList = hotelRoomTypeResult.getResultlist();
            roomtypeBaseParamDto.setRmtypes(rmtypeList.stream().map(rmtypeDto -> rmtypeDto.getRmtype()).collect(Collectors.toList()));
            QueryResult<L2RHotelRmtypePictureDto> rmtypeBigPicsResult = roomtypeFeignService.roomtypeBigPics(roomtypeBaseParamDto.paramToMap()).getQueryResult();
            QueryResult<L2RHotelRmtypePictureDto> rmtypePicsResult = roomtypeFeignService.roomtypePics(roomtypeBaseParamDto.paramToMap()).getQueryResult();

            //查询实际房量
            PmsRoomAvailInsideParamDto roomAvailParamDto=new PmsRoomAvailInsideParamDto();
            roomAvailParamDto.setLhotelGroupCode(marketApiParamDto.getLhotelGroupCode());
            roomAvailParamDto.setLhotelCode(marketApiParamDto.getLhotelCode());
            roomAvailParamDto.setL2RRmtypes(rmtypeList.stream().map(rmtypeDto -> rmtypeDto.getRmtype()).collect(Collectors.joining(",")));
            roomAvailParamDto.setArrtime(checkInDatetime);
            roomAvailParamDto.setDeptime(checkOutDatetime);
            QueryResult<PmsRmtypeAvailDto> roomAvailResult = pmsAvailFeignService.getRoomAvail(roomAvailParamDto.paramToMap()).getQueryResult();

            //查询集团价格池
            PricePool queryPricePool=new PricePool();
            queryPricePool.setLhotelGroupCode(marketApiParamDto.getLhotelGroupCode());
            QueryResult<PricePool> pricePoolResult = commonService.findAllEQ(PricePool.class, queryPricePool);
            List<PricePool> pricePoolList = pricePoolResult.getResultlist();

            if(hotelRoomTypeResult.getResultlist()!=null&&hotelRoomTypeResult.getResultlist().size()>0){
                TagBaseParamDto tagBaseParamDto=new TagBaseParamDto();
                tagBaseParamDto.setTagType(TagTypeConstant.MARKETING_TAG);
                QueryResult<TagBaseDto> tagBaseDtoQueryResult=tagBaseFeignService.getTagBaseList(tagBaseParamDto.paramToMap()).getQueryResult();
                Map<String,TagBaseDto> tagBaseMap=new HashMap<>();
                if(tagBaseDtoQueryResult.getResultlist()!=null){
                    for(TagBaseDto tagBase:tagBaseDtoQueryResult.getResultlist()){
                        tagBaseMap.put(tagBase.getTagCode(),tagBase);
                    }
                }
                //查询活动价格池
                L2RCondition priceConfition=new L2RCondition();
                priceConfition.setAndConditions(new ConditionDetail[]{
                        new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ,marketApiParamDto.getLhotelGroupCode()),
                        new ConditionDetail(MarketingCampaignsPrice.MarketingCampaignsPrice_.pbChannel.toString(), CriteriaUtil.Operator.EQ,marketApiParamDto.getPbChannel()),
                        new ConditionDetail(BaseEntity.BaseEntity_.isHalt.toString(), CriteriaUtil.Operator.EQ,DefaultValue.F),
                        new ConditionDetail(MarketingCampaignsPrice.MarketingCampaignsPrice_.mcCode.toString(), CriteriaUtil.Operator.IN,mcCodeList)
                });
                QueryResult<MarketingCampaignsPrice> marketingPricePoolResult = commonService.findAllByCondition(MarketingCampaignsPrice.class, priceConfition);
                List<MarketingCampaignsPrice> mcpList = marketingPricePoolResult.getResultlist();
                List<MarketingApiRmtypeDtoL2R> marketingRmtypeDtos=new ArrayList<>();

                //查询基价
                QueryResult<PriceStaticMapper> priceStaticResult = marketingService.getRmtypeStaticPrice(marketApiParamDto.getLhotelGroupCode(), marketApiParamDto.getLhotelCode(),null, null, checkInDatetime, checkOutDatetime);
                List<PriceStaticMapper> priceStatics=priceStaticResult.getResultlist();


                //遍历房型
                for(L2RRoomtypeDto rmtype:rmtypeList){

                    List<PmsRmtypeAvailDto> roomAvailList = roomAvailResult.getResultlist();

                    BigDecimal rmtypeMinPrice=new BigDecimal(999999);
                    MarketingApiRmtypeDtoL2R marketingApiRmtypeDto=ClassConverUtil.copyProperties(rmtype,MarketingApiRmtypeDtoL2R.class);
                    if(rmtypeBigPicsResult.getResultlist()!=null&&rmtypeBigPicsResult.getResultlist().size()>0){
                        Optional<L2RHotelRmtypePictureDto> bigPicDto = rmtypeBigPicsResult.getResultlist().stream()
                                .filter(picDto -> StringUtil.isNotBlank(picDto.getRmtype()) && picDto.getRmtype().equals(marketingApiRmtypeDto.getRmtype()))
                                .findFirst();
                        marketingApiRmtypeDto.setBigPic(bigPicDto.orElse(null));
                    }
                    List<L2RHotelRmtypePictureDto> rmtypePics=new ArrayList<>();
                    if(rmtypePicsResult.getResultlist()!=null&&rmtypePicsResult.getResultlist().size()>0){
                        for(L2RHotelRmtypePictureDto result:rmtypePicsResult.getResultlist()){
                            if(rmtype.getRmtype().equals(result.getRmtype())){
                                rmtypePics.add(result);
                            }
                        }
                    }
                    marketingApiRmtypeDto.setPics(rmtypePics);
                    //查询价格
                    List<MarketingApiDetailDto> marketingApiDetailDtos=new ArrayList<>();
                    Boolean saleNumEnough=false;
                    HashMap<String,BigDecimal> rmtypeRackPriceMap=new HashMap<>();
                    for(PriceStaticMapper priceStatic:priceStatics){
                        if(rmtype.getRmtype().equals(priceStatic.getRmtype())&&
                                DateUtil.format(checkInDate,DateUtil.webFormat).equals(DateUtil.format(priceStatic.getDate(),DateUtil.webFormat))){
                            rmtypeRackPriceMap.put(priceStatic.getPriceCode(),priceStatic.getPrice());
                        }
                    }
                    if(rmtypeRackPriceMap!=null&&rmtypeRackPriceMap.size()>0){
                        if(marketingDetailList!=null&&marketingDetailList.size()>0){
                            //遍历产品
                            for(MarketingCampaignsDetail marketingDetail:marketingDetailList){
                                if(rmtype.getRmtype().equals(marketingDetail.getRmtype())){
                                    MarketingApiDetailDto marketingApiDetailDto=null;
                                    MarketingMapper marketing = marketingMap.get(marketingDetail.getMcCode());
                                    if(marketing!=null){
                                        marketingApiDetailDto=ClassConverUtil.copyProperties(marketing, MarketingApiDetailDto.class);
                                        if(StringUtil.isNotBlank(marketingApiDetailDto.getMcTag())){
                                            String[] mcTagArr=StringUtils.commaDelimitedListToStringArray(marketingApiDetailDto.getMcTag());
                                            List<TagBaseDto> tagBaseDtos=new ArrayList<>();
                                            for(String mcTag:mcTagArr){
                                                TagBaseDto tagBaseDto = tagBaseMap.get(mcTag);
                                                if(tagBaseDto!=null){
                                                    tagBaseDtos.add(tagBaseDto);
                                                }
                                            }
                                            marketingApiDetailDto.setTagBaseDtos(tagBaseDtos);
                                        }
                                        marketingApiDetailDto.setLhotelCode(marketingDetail.getLhotelCode());
                                        if(rmtypeRackPriceMap.get(marketing.getPriceCode())!=null){
                                            marketingApiDetailDto.setRackPrice(rmtypeRackPriceMap.get(marketing.getPriceCode()));
                                        }else {
                                            marketingApiDetailDto.setRackPrice(new BigDecimal(-1000));
                                        }
                                        marketingApiDetailDto.setMcdName(MarketingUtil.getMcdName(marketing.getMcName(),rmtype.getName()));
                                    }
                                    marketingApiDetailDto.setIsClosed(DefaultValue.F);
                                    marketingApiDetailDto.setMcdCode(marketingDetail.getMcCode());
                                    marketingApiDetailDto.setId(marketingDetail.getId());
                                    List<MarketingApiPriceDto> marketingApiPriceDtos=new ArrayList<>();
                                    //计算价格
                                    if(new BigDecimal(-1000).compareTo(marketingApiDetailDto.getRackPrice())!=0){
                                        for(MarketingCampaignsPrice mcp:mcpList){
                                            if(marketingDetail.getMcCode().equals(mcp.getMcCode())){
                                                for(PricePool pricePool:pricePoolList){
                                                    if(pricePool.getPoolCode().equals(mcp.getPoolCode())){
                                                        BigDecimal firstPrice = PricePoolUtil.getPriceResult(marketingApiDetailDto.getRackPrice(),pricePool.getCarryType(),pricePool.getMultiplyValueSale(),pricePool.getAddValueSale());
                                                        if(rmtypeMinPrice.compareTo(firstPrice)>=0){
                                                            rmtypeMinPrice=firstPrice;
                                                        }
                                                        MarketingApiPriceDto marketingApiPrice = ClassConverUtil.copyProperties(mcp, MarketingApiPriceDto.class);
                                                        marketingApiPrice.setLhotelCode(marketingDetail.getLhotelCode());
                                                        marketingApiPrice.setFirstPrice(firstPrice);
                                                        marketingApiPriceDtos.add(marketingApiPrice);
                                                        if(memberLevel.equals(mcp.getMemberLevel())||MemberConstant.MEMBER_LEVEL.ALL.equals(mcp.getMemberLevel())){
                                                            marketingApiDetailDto.setCurrentPrice(firstPrice);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    Integer minSaleNum=9999;
                                    HashMap<String,MarketingCampaignsStock> mcsMap=new HashMap<>();
                                    HashMap<String,MarketingCampaignsStockSold> mcsdMap=new HashMap<>();

                                    if(marketingStockList!=null){
                                        for(MarketingCampaignsStock marketingStock:marketingStockList){
                                            if(marketingStock.getMcdCode().equals(marketingDetail.getMcdCode())){
                                                mcsMap.put(DateUtil.format(marketingStock.getRsvDate(),DateUtil.webFormat),marketingStock);
                                                if(marketingStock.getIsClosed().equals(DefaultValue.T)){
                                                    marketingApiDetailDto.setIsClosed(DefaultValue.T);
                                                }
                                            }
                                        }
                                    }
                                    if(marketingStockSoldList!=null){
                                        for(MarketingCampaignsStockSold marketingStockSold:marketingStockSoldList){
                                            if(marketingStockSold.getMcdCode().equals(marketingDetail.getMcdCode())){
                                                mcsdMap.put(DateUtil.format(marketingStockSold.getRsvDate(),DateUtil.webFormat),marketingStockSold);
                                            }
                                        }
                                    }

                                    if(roomAvailList!=null){
                                        for (PmsRmtypeAvailDto roomAvail:roomAvailList){
                                            if(roomAvail.getL2RRmtype().equals(rmtype.getRmtype())){
                                                String rsvDate=DateUtil.format(roomAvail.getRsvDate(),DateUtil.webFormat);
                                                MarketingCampaignsStock mcs = mcsMap.get(rsvDate);
                                                MarketingCampaignsStockSold mcsd = mcsdMap.get(rsvDate);
                                                minSaleNum=marketingService.getMinSaleNum(marketing.getUseRealAvail(),
                                                        marketing.getUseSetNum(),
                                                        minSaleNum,marketingDetail.getSetNum(),
                                                        mcs,mcsd,
                                                        roomAvail);
                                            }
                                        }
                                    }

                                    if(minSaleNum!=9999){
                                        if(minSaleNum<0){
                                            minSaleNum=0;
                                        }
                                        marketingApiDetailDto.setSaleNum(minSaleNum);
                                    }else {
                                        marketingApiDetailDto.setSaleNum(0);
                                    }
                                    if(marketingApiDetailDto.getSaleNum()>0){
                                        saleNumEnough=true;
                                    }
                                    marketingApiDetailDto.setMarketingApiPrices(marketingApiPriceDtos);
                                    if(new BigDecimal(-1000).compareTo(marketingApiDetailDto.getRackPrice())!=0&&marketingApiDetailDto.getCurrentPrice()!=null&&marketingApiDetailDto.getIsClosed().equals("F")){
                                        marketingApiDetailDtos.add(marketingApiDetailDto);
                                    }
                                }
                            }
                        }
                        if((new BigDecimal(999999).compareTo(rmtypeMinPrice))!=0){
                            marketingApiRmtypeDto.setRmtypeMinPrice(rmtypeMinPrice);
                        }
                    }
                    Collections.sort(marketingApiDetailDtos);
                    marketingApiRmtypeDto.setMarketingApiDetails(marketingApiDetailDtos);
                    marketingApiRmtypeDto.setSaleNumEnough(saleNumEnough);
                    marketingRmtypeDtos.add(marketingApiRmtypeDto);
                }
                Collections.sort(marketingRmtypeDtos);
                marketingApiDto.setMarketingApiRmtypes(marketingRmtypeDtos);
            }
        }
        return marketingApiDto;
    }

    /**
     * 可定检查
     * @param bookStockParamDto
     * @return
     * @throws Exception
     */
    @Override
    public BookStockApiDto checkBookStock(BookStockApiParamDto bookStockParamDto)throws Exception{
        String memberLevel= MemberConstant.MEMBER_LEVEL.L0;
        String checkInDatetimeNotime=DateUtil.format(DateUtil.parseDateWevFormat(bookStockParamDto.getCheckInDatetime()),DateUtil.newFormat);
        String checkOutDatetimeNotime=DateUtil.format(DateUtil.parseDateWevFormat(bookStockParamDto.getCheckOutDatetime()),DateUtil.newFormat);
        MemberSessionDto memberSession=null;
        if(StringUtil.isNotBlank(bookStockParamDto.getTicket())){
            memberSession = ApiThreadLocal.getMemberSessionThreadLocal();
            memberLevel=memberSession.getMemberLevel();
        }
        //查询产品
        MarketingCampaignsDetail mcd=commonService.findOneById(MarketingCampaignsDetail.class,bookStockParamDto.getId());

        //查询价格池
        MarketingCampaignsPrice querymcp=new MarketingCampaignsPrice();
        querymcp.setLhotelGroupCode(mcd.getLhotelGroupCode());
        querymcp.setMemberLevel(memberLevel);
        querymcp.setMcCode(mcd.getMcCode());
        querymcp.setPbChannel(bookStockParamDto.getPbChannel());
        MarketingCampaignsPrice mcp = commonService.findOneEQ(MarketingCampaignsPrice.class, querymcp);
        PricePool querypp=new PricePool();
        querypp.setLhotelGroupCode(mcd.getLhotelGroupCode());
        querypp.setPoolCode(mcp.getPoolCode());
        PricePool pp = commonService.findOneEQ(PricePool.class, querypp);
        MarketingCampaignsHotel querymch=new MarketingCampaignsHotel();
        querymch.setLhotelGroupCode(mcd.getLhotelGroupCode());
        querymch.setLhotelCode(mcd.getLhotelCode());
        querymch.setMcCode(mcd.getMcCode());
        MarketingCampaigns querymc=new MarketingCampaigns();
        querymc.setLhotelGroupCode(bookStockParamDto.getLhotelGroupCode());
        querymc.setMcCode(mcd.getMcCode());
        MarketingCampaignsChannel queryMcc=new MarketingCampaignsChannel();
        queryMcc.setLhotelGroupCode(bookStockParamDto.getLhotelGroupCode());
        queryMcc.setMcCode(mcd.getMcCode());
        queryMcc.setPbChannel(bookStockParamDto.getPbChannel());
        //查询活动
        MarketingCampaigns mc = commonService.findOneEQ(MarketingCampaigns.class, querymc);
        //查询酒店
        MarketingCampaignsHotel mch = commonService.findOneEQ(MarketingCampaignsHotel.class, querymch);
        //查询渠道
        MarketingCampaignsChannel mcc = commonService.findOneEQ(MarketingCampaignsChannel.class, queryMcc);
        L2RRateplan queryRP=new L2RRateplan();
        queryRP.setLhotelGroupCode(bookStockParamDto.getLhotelGroupCode());
        queryRP.setRpCode(mcc.getRpCode());
        L2RRateplan l2rRateplan = commonService.findOneEQ(L2RRateplan.class, queryRP);

        //查询房型基础价
        QueryResult<PriceStaticMapper> rmPriceResult = marketingService.getRmtypeStaticPrice(mcd.getLhotelGroupCode(), mcd.getLhotelCode(),mc.getPriceCode(), mcd.getRmtype(),
                checkInDatetimeNotime, checkOutDatetimeNotime);
        List<L2REverydayPriceDto> l2reverydayPriceList=new ArrayList<>();
        BigDecimal totalPrice=new BigDecimal(0);
        BigDecimal singleTotalPrice=new BigDecimal(0);
        for(PriceStaticMapper rmPrice:rmPriceResult.getResultlist()){
            if(mc.getPriceCode().equals(rmPrice.getPriceCode())){
                L2REverydayPriceDto l2reverydayPrice=new L2REverydayPriceDto();
                BigDecimal currentPrice= PricePoolUtil.getPriceResult(rmPrice.getPrice(),pp.getCarryType(),pp.getMultiplyValueSale(),pp.getAddValueSale());
                totalPrice=totalPrice.add(currentPrice.multiply(new BigDecimal(bookStockParamDto.getRmNum())));
                singleTotalPrice=singleTotalPrice.add(currentPrice);
                l2reverydayPrice.setRsvDate(rmPrice.getDate());
                l2reverydayPrice.setBasePrice(rmPrice.getPrice());
                l2reverydayPrice.setCurrentPrice(currentPrice);
                l2reverydayPrice.datetimeToString();
                l2reverydayPriceList.add(l2reverydayPrice);
            }
        }

        PmsReservationOptionParamDto pmsReservationOptionParamDto=new PmsReservationOptionParamDto();
        pmsReservationOptionParamDto.setPbChannel(mcc.getPbChannel());
        pmsReservationOptionParamDto.setResType(l2rRateplan.getResType());
        PmsReservationOptionDto pmsReservationOptionDto= pmsReservationOptionFeignService.getPmsReservationOption(pmsReservationOptionParamDto.paramToMap()).getResultInfo();

        PmsRoomAvailInsideParamDto roomAvailParamDto=new PmsRoomAvailInsideParamDto();
        roomAvailParamDto.setLhotelGroupCode(mcd.getLhotelGroupCode());
        roomAvailParamDto.setLhotelCode(mcd.getLhotelCode());
        roomAvailParamDto.setL2RRmtypes(mcd.getRmtype());
        roomAvailParamDto.setArrtime(checkInDatetimeNotime);
        roomAvailParamDto.setDeptime(checkOutDatetimeNotime);
        roomAvailParamDto.setOptId(bookStockParamDto.getOptId());
        roomAvailParamDto.setPmsRatecode(l2rRateplan.getPmsRatecode());
        roomAvailParamDto.setSalesChannel(pmsReservationOptionDto.getSalesChannel());
        QueryResult<PmsRmtypeAvailDto> roomAvailResult = pmsAvailFeignService.getRoomAvailDirect(roomAvailParamDto.paramToMap()).getQueryResult();
        List<PmsRmtypeAvailDto> roomAvailList = roomAvailResult.getResultlist();
        L2RCondition stockConfition=new L2RCondition();
        stockConfition.setAndConditions(new ConditionDetail[]{
                new ConditionDetail(BaseEntity.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ,mcd.getLhotelGroupCode()),
                new ConditionDetail(BaseEntity.BaseEntity_.lhotelCode.toString(), CriteriaUtil.Operator.EQ,mcd.getLhotelCode()),
                new ConditionDetail(MarketingCampaignsStock.MarketingCampaignsStock_.mcdCode.toString(), CriteriaUtil.Operator.EQ,mcd.getMcdCode()),
                new ConditionDetail(MarketingCampaignsStock.MarketingCampaignsStock_.rsvDate.toString(), CriteriaUtil.Operator.GTE,DateUtil.parseDateNewFormat(checkInDatetimeNotime)),
                new ConditionDetail(MarketingCampaignsStock.MarketingCampaignsStock_.rsvDate.toString(), CriteriaUtil.Operator.LT,DateUtil.parseDateNewFormat(checkOutDatetimeNotime))
        });
        QueryResult<MarketingCampaignsStock> marketingStockResult = commonService.findAllByCondition(MarketingCampaignsStock.class, stockConfition);
        List<MarketingCampaignsStock> marketingStockList = marketingStockResult.getResultlist();
        QueryResult<MarketingCampaignsStockSold> marketingStockSoldResult = commonService.findAllByCondition(MarketingCampaignsStockSold.class, stockConfition);
        List<MarketingCampaignsStockSold> marketingStockSoldList = marketingStockSoldResult.getResultlist();


        boolean isBookableFlag=true;
        Integer minSaleNum=9999;
        HashMap<String,MarketingCampaignsStock> mcsMap=new HashMap<>();
        HashMap<String,MarketingCampaignsStockSold> mcsdMap=new HashMap<>();

        if(marketingStockList!=null){
            for(MarketingCampaignsStock marketingStock:marketingStockList){
                mcsMap.put(DateUtil.format(marketingStock.getRsvDate(),DateUtil.webFormat),marketingStock);
                if(marketingStock.getIsClosed().equals(DefaultValue.T)){
                    isBookableFlag=false;
                }
            }
        }
        if(marketingStockSoldList!=null){
            for(MarketingCampaignsStockSold marketingStockSold:marketingStockSoldList){
                mcsdMap.put(DateUtil.format(marketingStockSold.getRsvDate(),DateUtil.webFormat),marketingStockSold);
            }
        }

        if(roomAvailList!=null){
            List<MarketingStockDto> marketingStockDtos=new ArrayList<>();

            for (PmsRmtypeAvailDto roomAvail:roomAvailList){
                String rsvDate=DateUtil.format(roomAvail.getRsvDate(),DateUtil.webFormat);
                MarketingCampaignsStock mcs = mcsMap.get(rsvDate);
                MarketingCampaignsStockSold mcsd = mcsdMap.get(rsvDate);
                int currentMinSaleNum=marketingService.getSaleNum(mc.getUseRealAvail(),mc.getUseSetNum(),mcd.getSetNum(), mcs, mcsd,roomAvail);
                minSaleNum=marketingService.getMinSaleNum(mc.getUseRealAvail(),
                        mc.getUseSetNum(),
                        minSaleNum,mcd.getSetNum(),
                        mcs,mcsd,
                        roomAvail);
                if(currentMinSaleNum<=0){
                    MarketingStockDto marketingStockDto=new MarketingStockDto(mcd.getLhotelGroupCode(),
                            mcd.getLhotelCode(),
                            mcd.getMcdCode(),
                            mcd.getRmtype(),
                            rsvDate,
                            DateUtil.getDateWeek(DateUtil.parseDateWevFormat(rsvDate)),
                            null,
                            DefaultValue.T);
                    marketingStockDtos.add(marketingStockDto);
                }
            }
            //抛消息处理活动产品房量关闭
            if(marketingStockDtos.size()>0){
                MarketingStockBaseParamDto marketingStockBaseParamDto=new MarketingStockBaseParamDto();
                marketingStockBaseParamDto.setLhotelCode(mcd.getLhotelCode());
                marketingStockBaseParamDto.setMcdCode(mcd.getMcdCode());
                marketingStockBaseParamDto.setMarketingStockDtoList(marketingStockDtos);
                mnsUtil.putMessageToQueue(OptimusMnsConstant.QUEUE_MARKETING_STOCK,JacksonUtil.beanToJson(marketingStockBaseParamDto));
            }
        }

        BookStockApiDto bookStockApiDto=new BookStockApiDto();
        bookStockApiDto.setLhotelGroupCode(mcd.getLhotelGroupCode());
        bookStockApiDto.setLhotelCode(mcd.getLhotelCode());
        bookStockApiDto.setMcCode(mcd.getMcCode());
        bookStockApiDto.setMcdCode(mcd.getMcdCode());
        bookStockApiDto.setMcdName(MarketingUtil.getMcdName(mc.getMcName(),mcd.getRmtypeName()));
        bookStockApiDto.setMcdNameEn(MarketingUtil.getMcdName(mc.getMcNameEn(),mcd.getRmtypeNameEn()));
        bookStockApiDto.setRmtype(mcd.getRmtype());
        bookStockApiDto.setEverydayPrices(l2reverydayPriceList);
        bookStockApiDto.setHotelName(mch.getName());
        bookStockApiDto.setHotelNameEn(mch.getNameEn());
        bookStockApiDto.setRmtypeName(mcd.getRmtypeName());
        bookStockApiDto.setRmtypeNameEn(mcd.getRmtypeNameEn());
        bookStockApiDto.setSingleTotalPrice(singleTotalPrice);
        bookStockApiDto.setDayNum(DateUtil.dateNum(DateUtil.parseDateNewFormat(checkInDatetimeNotime),DateUtil.parseDateNewFormat(checkOutDatetimeNotime)));
        bookStockApiDto.setL2RRateplanDto(ClassConverUtil.copyPropertiesToDto(l2rRateplan,L2RRateplanDto.class, false));
        if(minSaleNum!=9999){
            if(minSaleNum<0){
                minSaleNum=0;
            }
            bookStockApiDto.setMinSaleNum(minSaleNum);
        }else {
            bookStockApiDto.setIsBookable(DefaultValue.F);
        }
        if(isBookableFlag){
            bookStockApiDto.setIsBookable(DefaultValue.T);
        }
        if(minSaleNum.equals(0)||bookStockParamDto.getRmNum()>minSaleNum){
            bookStockApiDto.setIsBookable(DefaultValue.F);
        }
        bookStockApiDto.setTotalPrice(totalPrice);
        if(!DefaultValue.NONE.equals(l2rRateplan.getPointRule())&&DefaultValue.T.equals(memberSession.getIsMember())){
            PointBaseParamDto pointBaseParamDto=new PointBaseParamDto();
            pointBaseParamDto.setLhotelCode(mcd.getLhotelCode());
            pointBaseParamDto.setL2rMemberNo(memberSession.getMemberNo());
            pointBaseParamDto.setTotalPriceSale(totalPrice);
            pointBaseParamDto.setArrDateStr(checkInDatetimeNotime);
            pointBaseParamDto.setDepDateStr(checkOutDatetimeNotime);
            pointBaseParamDto.setPointRuleCode(l2rRateplan.getPointRule());
            PointCheckDto pointCheckDto = pointFeignService.checkPointRule(pointBaseParamDto.paramToMap()).getResultInfo();
            bookStockApiDto.setCanUsePoint(pointCheckDto.getCanUsePoint());
            bookStockApiDto.setUsePoint(pointCheckDto.getUsePoint());
            bookStockApiDto.setPointToMoney(pointCheckDto.getPointToMoney());
            bookStockApiDto.setRealPrice(totalPrice.subtract(pointCheckDto.getPointToMoney()));
        }
        String cancelPolicyDes;
        if(null!=l2rRateplan.getCancelType()){
            if(BaseRateplanConstant.CANCELTYPE.CUSTOM.equals(l2rRateplan.getCancelType())) {
                L2RCancelRuleDto cancelRule = JacksonUtil.jsonToBean(l2rRateplan.getCancelRule(), L2RCancelRuleDto.class);
                StringBuffer sb = new StringBuffer();
                Date canCancelDate = DateUtil.addHours(DateUtil.parseDateNoTime(bookStockParamDto.getCheckInDate()), 24 - cancelRule.getCancelHour());
                if(canCancelDate.getTime()>=bookStockParamDto.getCheckInDate().getTime()){
                    sb.append("此订单为预付订单，预订成功后:");
                }else {
                    sb.append("此订单为预付订单，预订成功后，" + DateUtil.getNewFormatDateString(canCancelDate) + "前可以取消：");
                }
                Date noneDate = null;
                Date halfDate = null;
                for (L2RCancelRuleBaseDto ruleBase : cancelRule.getL2RCancelRuleBaseDtos()) {
                    Date dateNode = DateUtil.addHours(DateUtil.parseDateNoTime(bookStockParamDto.getCheckInDate()), 24 - ruleBase.getHourNode());
                    if ("NONE".equals(ruleBase.getRuleCode())) {
                        noneDate = dateNode;
                    }
                    if ("HALF".equals(ruleBase.getRuleCode())) {
                        halfDate = dateNode;
                    }

                }
                for (L2RCancelRuleBaseDto ruleBase : cancelRule.getL2RCancelRuleBaseDtos()) {
                    if ("NONE".equals(ruleBase.getRuleCode())) {
                        sb.append("在" + DateUtil.getNewFormatDateString(noneDate) + "之前取消，全额退款;");
                    }
                    if ("HALF".equals(ruleBase.getRuleCode())) {
                        sb.append("在" + DateUtil.getNewFormatDateString(noneDate) + "-" + DateUtil.getNewFormatDateString(halfDate) + "之间取消，将扣除首晚房费的" + ruleBase.getMultiplyValue().multiply(new BigDecimal(100)) + "%，合计" + l2reverydayPriceList.get(0).getCurrentPrice().multiply(ruleBase.getMultiplyValue()) + "元;");
                    }
                    if ("ALL".equals(ruleBase.getRuleCode())) {
                        sb.append("在" + DateUtil.getNewFormatDateString(halfDate) + "之后取消，将扣除首晚房费" + l2reverydayPriceList.get(0).getCurrentPrice() + "元;");
                    }

                }
                cancelPolicyDes=sb.toString();
            }else if (BaseRateplanConstant.CANCELTYPE.ALLOW.equals(l2rRateplan.getCancelType())) {
                cancelPolicyDes="当前订单预定成功后，免费取消！";
            }else {
                cancelPolicyDes="当前订单预定成功后，不可取消！";
            }
        } else {
            cancelPolicyDes="当前订单预定成功后，免费取消！";
        }
        bookStockApiDto.setCancelPolicyDes(cancelPolicyDes);
        return bookStockApiDto;
    }
}
